package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.commons.constants.CommonConstants;
import com.xuecheng.commons.constants.CourseConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.BindTeachplanMediaDto;
import com.xuecheng.commons.model.dto.TeachplanDto;
import com.xuecheng.commons.model.vo.MediaVo;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.model.vo.TeachplanVo;
import com.xuecheng.commons.utils.AuthInfoThreadLocal;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.domain.CourseBase;
import com.xuecheng.content.domain.Teachplan;
import com.xuecheng.content.domain.TeachplanMedia;
import com.xuecheng.content.mappers.TeachplanMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.xuecheng.content.service.TeachplanMediaService;
import com.xuecheng.content.service.TeachplanService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.media.api.MediaClient;
import com.xuecheng.web.exceptions.BusinessException;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程计划 服务实现类
 * </p>
 *
 * @author 七安
 * @since 2022-09-17
 */
@Service
public class TeachplanServiceImpl extends ServiceImpl<TeachplanMapper, Teachplan> implements TeachplanService {

    @Autowired
    private TeachplanMapper teachplanMapper;

    @Autowired
    private CourseBaseService courseBaseService;

    @Autowired
    private MediaClient mediaClient;

    @Autowired
    private TeachplanMediaService teachplanMediaService;

    /**
     * 根据课程id查询课程计划。（包括1，2，3级结构）
     *
     * @param courseId 课程id
     * @return 查到的结果
     */
    @Override
    public TeachplanVo findTeachplanByCourseId(Long courseId) {
        List<TeachplanVo> teachplanVoList = teachplanMapper.findTeachplanByCourseId(courseId);
        //使用Stream流筛选1级结构
        TeachplanVo teachplanVo = teachplanVoList.stream().filter(vo -> vo.getGrade() == 1).findFirst().get();
        //筛选2级结构
        List<TeachplanVo> twoTeachplanVo = teachplanVoList.stream().filter(vo -> vo.getGrade() == 2).collect(Collectors.toList());
        //筛选3级结构
        for (TeachplanVo twoVo : twoTeachplanVo) {
            //3级结构的父id必须等于2级的id
            List<TeachplanVo> threeTeachplanVo = teachplanVoList.stream()
                    .filter(vo -> vo.getGrade() == 3 && vo.getParentid().equals(twoVo.getId()))
                    .collect(Collectors.toList());
            //将3级结构放入2级结构中
            twoVo.setTeachPlanTreeNodes(threeTeachplanVo);
        }
        //将2级结构放入1级结构中
        teachplanVo.setTeachPlanTreeNodes(twoTeachplanVo);
        //返回1级结构
        return teachplanVo;
    }

    /**
     * 保存或更新课程计划
     *
     * @param teachplanDto 要存的内容
     */
    @Override
    public void saveOrUpdatePlan(TeachplanDto teachplanDto) throws BusinessException {
        //根据课程id查询课程
        CourseBase courseBase = courseBaseService.getById(teachplanDto.getCourseId());
        //判断课程状态是否能够修改
        if (courseBase == null ||
                CourseConstants.AUDIT_COMMIT_STATUS.equals(courseBase.getAuditStatus()) ||
                CourseConstants.AUDIT_PASTED_STATUS.equals(courseBase.getAuditStatus()) ||
                CourseConstants.AUDIT_PUBLISHED_STATUS.equals(courseBase.getAuditStatus())) {
            throw new BusinessException(ErrorCode.ADDEERROR);
        }
        //转为实体对象
        Teachplan teachplan = BeanHelper.copyProperties(teachplanDto, Teachplan.class);
        //判断父级id是否为空
        if (teachplan.getParentid() == null) {
            //查询1级结构
            LambdaQueryWrapper<Teachplan> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Teachplan::getGrade, CourseConstants.FIRST_LEVEL);
            wrapper.eq(Teachplan::getCourseId, teachplan.getCourseId());
            //一级结构
            Teachplan one = teachplanMapper.selectOne(wrapper);
            //将ID设置给传来的teachplan
            teachplan.setParentid(one.getId());
        }
        //判断当前id是不是null
        if (teachplan.getId() == null) {
            //添加
            this.save(teachplan);
            //判断是否为3级章节
            if (teachplan.getGrade().equals(CourseConstants.THIRD_LEVEL)) {
                //修改章节数量
                courseBase.setPlanNum(courseBase.getPlanNum() + 1);
                //更新
                courseBaseService.updateById(courseBase);
            }
        }
        if (teachplan.getId() != null) {
            //否则就是修改
            this.updateById(teachplan);
        }
    }

    /**
     * 根据id删除章节
     *
     * @param id 要删除的id
     */
    @Override
    public void deletePlanById(Long id) throws BusinessException {
        //根据id查询章节等级
        Teachplan teachplan = teachplanMapper.selectById(id);
        if (ObjectUtils.isEmpty(teachplan)) {
            throw new BusinessException(ErrorCode.DELETEERROR);
        }
        if (teachplan.getGrade().equals(CourseConstants.THIRD_LEVEL)) {
            //课程上的小节数-1
            CourseBase courseBase = courseBaseService.getById(teachplan.getCourseId());
            if (courseBase.getPlanNum() > 0) {
                courseBase.setPlanNum(courseBase.getPlanNum() - 1);
                courseBaseService.updateById(courseBase);
            }
        }
        teachplanMapper.deleteById(id);
    }

    /**
     * 课程绑定媒资
     *
     * @param bindTeachplanMediaDto 接收
     * @return 结果
     */
    @Override
    public ResponseResult mediaBindingTeachplan(BindTeachplanMediaDto bindTeachplanMediaDto) throws BusinessException {
        //判空
        if (ObjectUtils.isEmpty(bindTeachplanMediaDto) || bindTeachplanMediaDto.getTeachplanId() == null) {
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        //根据课程计划id查询课程计划
        Teachplan teachplan = teachplanMapper.selectById(bindTeachplanMediaDto.getTeachplanId());
        //判断空与删除状态
        if (ObjectUtils.isEmpty(teachplan) || CommonConstants.DELETE_FLAG.equals(teachplan.getStatus())) {
            throw new BusinessException(ErrorCode.PARAMSERROR);
        }
        //获取课程id查询课程
        CourseBase courseBase = courseBaseService.getById(teachplan.getCourseId());
        //判断删除状态
        if (CommonConstants.DELETE_FLAG.equals(courseBase.getStatus())) {
            throw new BusinessException(ErrorCode.PARAMSERROR);
        }
        //判断当前课程的状态
        String auditStatus = courseBase.getAuditStatus();
        if (StringUtils.isEmpty(auditStatus) ||
                CourseConstants.AUDIT_COMMIT_STATUS.equals(auditStatus) ||
                CourseConstants.AUDIT_PASTED_STATUS.equals(auditStatus) ||
                CourseConstants.AUDIT_PUBLISHED_STATUS.equals(auditStatus) ||
                CourseConstants.AUDIT_UNLINE_STATUS.equals(auditStatus)) {
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        //调用feign接口查询媒资
        ResponseResult<MediaVo> responseResult = mediaClient.findMediaById(bindTeachplanMediaDto.getMediaId());
        //判断
        if (responseResult.getCode() != ErrorCode.SUCCESS.getCode()) {
            throw new BusinessException(ErrorCode.PARAMSERROR);
        }
        MediaVo media = responseResult.getData();
        //查询媒资课程绑定表
        LambdaQueryWrapper<TeachplanMedia> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TeachplanMedia::getTeachplanId, teachplan.getId());
        //一个课程计划只能绑定一个媒资
        TeachplanMedia tm = teachplanMediaService.getOne(wrapper);
        //判空
        if (ObjectUtils.isEmpty(tm)) {
            tm = new TeachplanMedia();
            //封装数据
            //设置媒资id
            tm.setMediaId(media.getId());
            //课程计划id
            tm.setTeachplanId(teachplan.getId());
            //课程id
            tm.setCourseId(courseBase.getId());
            //视屏名称
            tm.setMediaFilename(media.getFilename());
            //创建用户
            tm.setCreatePeople(AuthInfoThreadLocal.getUserId().toString());
            //机构
            tm.setCompanyId(AuthInfoThreadLocal.getCompanyId());
            //插入数据
            teachplanMediaService.save(tm);
        } else {
            //修改数据
            tm.setMediaId(media.getId());
            tm.setTeachplanId(teachplan.getId());
            teachplanMediaService.updateById(tm);
        }
        return ResponseResult.okResult();
    }

    /**
     * 删除媒资绑定
     *
     * @param teachPlanMediaId 媒资id
     * @param courseBaseId     课程id
     * @return 结果
     */
    @Override
    public ResponseResult deleteMediaBinding(Long teachPlanMediaId, Long courseBaseId) throws BusinessException {
        Boolean b = teachplanMediaService.deleteMediaBinding(teachPlanMediaId, courseBaseId);
        //判断
        if (!b) {
            throw new BusinessException(ErrorCode.NOTFOUND);
        }
        return ResponseResult.okResult();
    }
}
